package edu.office.applicationRepository;

import edu.office.entities.School;
import edu.office.entities.Subject;
import edu.office.entities.TeacherAdmin;
import edu.office.entities.Teacschoolsubject;
import edu.office.tools.EOMessage;
import edu.office.tools.EOMessage1;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.inject.Named;

import java.util.*;


@Named("schoolRepositoryA")
@ApplicationScoped
public class SchoolRepository extends ApplicationCommonRepository<School> {

    @Inject
    TeacschoolsubjectRepository teacschoolsubjectRepository;
    HashMap<Integer, List<School>> school4Major = new HashMap<>();
    HashMap<Integer, School> idSchooldMap = new HashMap<>();
    private Set<School> schoolsOnLeaves = new HashSet<>();
    private List<School> schoolRootList = new LinkedList<>();
    private List<School> allSchools = new LinkedList<>();
    private List<School> parentSchools = new LinkedList<>();

    public List<School> getParentSchools() {
        if (parentSchools.isEmpty() || isDataChanged()) {
            parentSchools.clear();
            List<Integer> parentIds = new LinkedList<>();
            getAllSchools().forEach(school -> {
                parentIds.add(school.getPARENTID());
            });
            getAllSchools().forEach(school -> {
                if (parentIds.contains(school.getID()))
                    parentSchools.add(school);
            });
        }
        return parentSchools;
    }

    public List<School> getAllSchools() {
        if (allSchools.isEmpty() || isDataChanged()) allSchools = listAll();
        return allSchools;
    }

    public List<School> getRootSchoolList() {
        if (isDataChanged() || schoolRootList.isEmpty()) {
            schoolRootList.clear();
            getAllSchools().forEach((School school) -> {
                if (null == school.getPARENTID()) {
                    schoolRootList.add(school);
                }
            });
        }
        return schoolRootList;
    }

    public Set<School> getSchoolsOnLeaves() {
        if (schoolsOnLeaves.isEmpty() || isDataChanged()) {
            schoolsOnLeaves.clear();
            for (School school : getAllSchools()) {
                if (!getParentSchools().contains(school)) {
                    schoolsOnLeaves.add(school);
                }
            }
        }
        return schoolsOnLeaves;
    }

    public String getSchoolTreeLikeJSON() {
        StringBuilder result = new StringBuilder();
        List<School> allSchools = getAllSchools();
        for (School school : allSchools) {
            result.append("{").append("id:")
                    .append(school.getID())
                    .append(",")
                    .append("pId:")
                    .append(school.getPARENTID() == null ? 0 : String.valueOf(school.getPARENTID()))
                    .append(",name:\"")
                    .append(school.getNAME())
                    .append("\"}__");
        }
        String finalResult = result.toString();
        finalResult = finalResult.substring(0, finalResult.length() - 2);
        return finalResult;
    }

    public List<School> getSchools4Teacher(TeacherAdmin teacherAdmin) {
        List<School> result = new ArrayList<>();
        List<Teacschoolsubject> teacschoolsubjectList = teacschoolsubjectRepository.list("TEACHERID", teacherAdmin.getID());
        List<Integer> ids = new LinkedList<>();
        teacschoolsubjectList.forEach(teaschSub ->
                ids.add(teaschSub.getSCHOOLID()));
        getAllSchools().forEach(school -> {
            if (ids.contains(school.getID())) {
                result.add(school);
            }
        });
        return result;
    }

    public List<School> getSchool4Major(Integer majorId) {
        return prepareSchool4Major().get(majorId);
    }

    private HashMap<Integer, List<School>> prepareSchool4Major() {
        if (school4Major.isEmpty() || isDataChanged()) {
            school4Major.clear();
            getAllSchools().forEach(school -> {
                if (school4Major.get(school.getMAJORID()) == null)
                    school4Major.put(school.getMAJORID(), new LinkedList<>());
                school4Major.get(school.getMAJORID()).add(school);
            });
        }
        return school4Major;
    }

    public Set<School> getCurrentSubjectSchools(Subject subject) {
        //当前开设这门课的班级
        Set<School> resuSchools = new HashSet<>();
        Set<Teacschoolsubject> teaschsubSet = teacschoolsubjectRepository.getTeacschoolsubjects4Subject(subject);
        for (Teacschoolsubject tss : teaschsubSet) {
            resuSchools.add(getSchoolById(tss.getSCHOOLID()));
        }
        return resuSchools;
    }


    public List<School> getAllClasses4SubjectAndTeacher(Integer subjectId, Integer teacherId) {
        List<Integer> classList = new LinkedList<>();
        String temSQL = "select * from teacschoolsubject where teacherid=" + teacherId + " and subjectid=" + subjectId;
        List<Teacschoolsubject> teacschoolsubjects = teacschoolsubjectRepository.find(temSQL).list();
        for (Teacschoolsubject t : teacschoolsubjects) {
            classList.add(t.getSCHOOLID());
        }
        List<School> result = new LinkedList<>();
        getAllSchools().forEach(school -> {
            if (classList.contains(school.getID())) result.add(school);
        });
        return result;
    }

    public List<School> searchByName(String searchName) {
        return find("NAME", searchName).list();
    }


    public String mycreate(School school) {
        if (find("NAME", school.getNAME()).list().isEmpty()) {
            create(school);
            return EOMessage.getEOMessageENUM(EOMessage1.Succeed);
        } else {
            return EOMessage.getEOMessageENUM(EOMessage1.Already_Exist);
        }
    }

    public School getSchoolById(Integer id) {
        if (idSchooldMap.isEmpty() || isDataChanged()) {
            idSchooldMap.clear();
            getAllSchools().forEach(school -> {
                idSchooldMap.put(school.getID(), school);
            });
        }
        return idSchooldMap.get(id);
    }
}
